<!DOCTYPE html>
<html lang="en-us">
<head><head>
    <meta name="google-site-verification" content="9vIieCe-Qpd78QOmBl63rGtIVbhY6sYyuxX3j8XWBA4" />
    <meta name="baidu-site-verification" content="LRrmH41lz7" />
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <meta name="baidu-site-verification" content="HGLXRsUXC4" />

    
    <meta name="baidu-site-verification" content="code-ANZvlnN0Xr" />

    
    <meta name="description" content="这一篇，我们为大家带来了开发过程中，最常接触到的同步异步调用解析。本文会介绍下同步异步的使用场景，以及 SOFARPC 中的代码实现机制，为了方便大家理解和阅读代码。不会过多的设计代码实现细节，更多的还是希望大家从中有所收获，并能够独立阅读核心代码。">
    
    <meta name="keyword"  content="liangyuanpeng|LanLiang|OpenYurt|Knative|Pulsar|Prometheus|Halo||边缘计算kubernetes|Docker|CloudNative|Golang|Rust|Istio|微服务">
    <link rel="shortcut icon" href="img/logo.png">


    
    <meta property="og:image" content="https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg" />
    <meta name="twitter:image" content="https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg" />


    <title>转|SOFARPC线程模型剖析-liangyuanpeng的博客 | liangyuanpeng&#39;s Blog</title>

    <link rel="canonical" href="/post/sofarpc-modle/">

    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/iDisqus.min.css"/>

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369744/hugo/css/bootstrap.min.css">

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/hux-blog.min.css">

    
    <link rel="stylesheet" href="https://res.cloudinary.com/lyp/raw/upload/v1537369740/hugo/css/syntax.css">

    
    <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    
    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369966/hugo/js/jquery.min.js"></script>

    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369966/hugo/js/bootstrap.min.js"></script>

    
    <script src="https://res.cloudinary.com/lyp/raw/upload/v1537369964/hugo/js/hux-blog.min.js"></script>

    
    <script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "f73bc0092aeb491d89984c0eb5a87ac2"}'></script>
</head>

</head>

<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Hi,I`m lan</a>
        </div>

        
        
        <div id="huxblog_navbar">
            <div class="navbar-collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li>
                        <a href="/">Home</a>
                    </li>
                    
                    <li>
                        <a href="categories/cloudnative">cloudnative</a>
                    </li>
                    
                    <li>
                        <a href="categories/devops">devops</a>
                    </li>
                    
                    <li>
                        <a href="categories/iot">iot</a>
                    </li>
                    
                    <li>
                        <a href="categories/kubernetes">kubernetes</a>
                    </li>
                    
                    <li>
                        <a href="categories/tech">tech</a>
                    </li>
                    

                    
		            <li>
                        <a href="search">SEARCH <img src="img/search.png" height="15" style="cursor: pointer;"></a>
		            </li>
                    
                </ul>
            </div>
        </div>
        
    </div>
    
</nav>
<script>
    
    
    
    var $body   = document.body;
    var $toggle = document.querySelector('.navbar-toggle');
    var $navbar = document.querySelector('#huxblog_navbar');
    var $collapse = document.querySelector('.navbar-collapse');

    $toggle.addEventListener('click', handleMagic)
    function handleMagic(e){
        if ($navbar.className.indexOf('in') > 0) {
        
            $navbar.className = " ";
            
            setTimeout(function(){
                
                if($navbar.className.indexOf('in') < 0) {
                    $collapse.style.height = "0px"
                }
            },400)
        }else{
        
            $collapse.style.height = "auto"
            $navbar.className += " in";
        }
    }
</script>




<style type="text/css">
    header.intro-header{
        background-image: url('https://res.cloudinary.com/lyp/image/upload/v1544363182/hugo/blog.github.io/e64ae3596ed565b8202d395d771665dd.jpg')
    }
</style>
<header class="intro-header" >
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <div class="tags">
                       
                       <a class="tag" href="/tags/rpc" title="rpc">
                           rpc
                        </a>
                        
                       <a class="tag" href="/tags/sofa" title="sofa">
                           sofa
                        </a>
                        
                       <a class="tag" href="/tags/sofastack" title="sofastack">
                           sofastack
                        </a>
                        
                       <a class="tag" href="/tags/middleware" title="Middleware">
                           Middleware
                        </a>
                        
                    </div>
                    <h1>转|SOFARPC线程模型剖析</h1>
                    <h2 class="subheading"></h2>
                    <span  class="meta">Posted by 梁远鹏 on 2018-12-09
                        
                        <span id="busuanzi_container_page_pv">|<span id="busuanzi_value_page_pv"></span><span>
                            <span id="/post/sofarpc-modle/" class="leancloud_visitors meta_data_item" data-flag-title="">
    <span class="post-meta-item-icon">
      <span class="octicon octicon-eye"></span> 
    </span>
    <i class="fa fa-eye"></i>
    <span class="old-visitors-count" style="display: none;"></span>
    <span class="leancloud-visitors-count"></span>
</span>






                            阅读 </span></span>|<span class="post-date">共3405字</span>，阅读约<span class="more-meta"> 7 分钟</span>
                        
                    </span>
                </div>
            </div>
        </div>
    </div>
</header>




<article>
    <div class="container">
        <div class="row">

            
            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                post-container">

		
                <header>
                <h2>TOC</h2>
                </header>
                <nav id="TableOfContents">
  <ul>
    <li><a href="#阻塞-io">阻塞 I/O</a></li>
    <li><a href="#非阻塞-io">非阻塞 I/O</a></li>
    <li><a href="#io-复用">I/O 复用</a></li>
    <li><a href="#信号驱动式-io">信号驱动式 I/O</a></li>
    <li><a href="#异步-io">异步 I/O</a></li>
    <li><a href="#汇总">汇总</a></li>
  </ul>

  <ul>
    <li><a href="#java-bio">JAVA BIO</a></li>
    <li><a href="#java-nio">JAVA NIO</a></li>
  </ul>

  <ul>
    <li>
      <ul>
        <li><a href="#单线程模型">单线程模型</a></li>
        <li><a href="#多线程模型">多线程模型</a></li>
        <li><a href="#主从多线程模型">主从多线程模型</a></li>
      </ul>
    </li>
  </ul>

  <ul>
    <li><a href="#整体线程模型">整体线程模型</a>
      <ul>
        <li><a href="#线程模型">线程模型</a></li>
        <li><a href="#默认执行步骤">默认执行步骤</a></li>
      </ul>
    </li>
    <li><a href="#自定义业务线程池">自定义业务线程池</a>
      <ul>
        <li><a href="#实现原理">实现原理</a></li>
        <li><a href="#使用方式">使用方式</a></li>
      </ul>
    </li>
  </ul>
</nav>
		
		<h1 id="前言">前言</h1>
<p>上一篇，我们介绍了 SOFARPC 同步异步的实现，本文我们将会介绍 SOFARPC 中的线程模型。</p>
<p>本文会从同步异步，阻塞非阻塞开始讲起，进而探讨常见的线程模型设计，之后，我们会介绍下 SOFABolt 中对 Netty 的模型使用<!-- raw HTML omitted --><!-- raw HTML omitted -->，最后 SOFARPC 在一次调用过程中各个步骤执行的线程。<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h1 id="几种常见的-io-模型">几种常见的 IO 模型</h1>
<p>首先介绍一下 Linux 的几种 IO 模型，以进程从 Socket 中读取数据为例。实际上，进程最终是通过 recvfrom 系统调用来读取数据。这个时候，系统内核在收到之后，根据 IO 模型的不同，处理是不同的。</p>
<p>注意，图下的红色部分表示阻塞时间。</p>
<h2 id="阻塞-io">阻塞 I/O</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348793/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536484777732-d96dfd95-d2f2-4f65-aa3b-b53b5fa1a379.png" alt="阻塞 IO.png | center | 747x326" title=""></p>
<p>阻塞 I/O(blocking I/O) 模型是最流行，最简单易用的 I/O 模型，默认情况下，所有套接字和文件描述符就是阻塞的。阻塞 I/O 将使请求进程阻塞，直到请求完成或出错。</p>
<h2 id="非阻塞-io">非阻塞 I/O</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348828/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536484784828-a2f5519d-f24e-4c2f-9a1e-9ccd2f3b586f.png" alt="非阻塞 IO.png | center | 747x322" title=""></p>
<p>非阻塞 I/O(nonblocking I/O)的含义：如果 I/O 操作会导致请求进程休眠，则不要把它挂起，也就是不会让出 CPU，而是返回一个错误告诉它（可能是 EWOULDBLOCK 或者 EAGAIN）。</p>
<h2 id="io-复用">I/O 复用</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348863/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536484789749-69680397-5830-4636-8fe4-fb208e8c9917.png" alt="IO 复用.png | center | 747x319" title=""></p>
<p>I/O 多路复用(I/O multiplexing)会用到 select 或者 poll 或者 epoll 函数，这几个函数也会使进程阻塞，但是和阻塞 I/O 所不同的的，函数可以同时阻塞多个 I/O 操作。而且可以同时对多个读操作，多个写操作的 I/O 函数进行检测，直到有数据可读或可写时，才真正调用 I/O 操作函数。</p>
<h2 id="信号驱动式-io">信号驱动式 I/O</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348923/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536484794971-5f21afc1-d27b-4e7c-8bdd-e6727f681e2d.png" alt="信号驱动.png | center | 747x319" title=""></p>
<p>信号驱动 I/O(signal-driver I/O)使用信号，让内核在描述符就绪时发送 SIGIO 信号通知我们进行处理，这时候我们就可以开始真正的读了。</p>
<h2 id="异步-io">异步 I/O</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348957/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536484800026-c94d6d86-9249-4be3-8335-20c31cf5e5d8.png" alt="异步 IO.png | center | 747x326" title=""></p>
<p>异步 I/O(asynchronous I/O)由 POSIX 规范定义，包含一系列以 aio 开头的接口。一般地说，这些函数的工作机制是：告知内核启动某个操作，并让内核在整个操作（包括将数据从内核空间拷贝到用户空间）完成后通知我们。</p>
<p>这种模型与信号驱动模型的主要区别是：信号驱动 I/O 是由内核通知我们何时可以启动一个 I/O 操作，而异步 I/O 模型是由内核通知我们 I/O 操作何时完成。</p>
<h2 id="汇总">汇总</h2>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544348994/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536485421523-edb84cd0-c96c-42ff-89d2-ed4acfb3e473.png" alt="总结.png | center | 747x293" title=""></p>
<p>综上，我们给出一个大家比较熟知的比较图。方便理解。</p>
<h1 id="java-bio--nio">JAVA BIO &amp; NIO</h1>
<p>在了解了内核层面上这几个线程模型之后，我们要给大家介绍下 JAVA BIO 和 JAVA NIO。</p>
<h2 id="java-bio">JAVA BIO</h2>
<p>首先我们给大家看一个直接使用 JAVA BIO 写得一个服务端。</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349034/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536722399340-1e5efe3b-33a2-48f0-9242-7f255d9b06c0.png" alt="carbon (1).png | center | 747x729" title=""></p>
<p>传统的BIO里面socket.read()，如果TCP RecvBuffer里没有数据，调用会一直阻塞，直到收到数据，返回读到的数据。</p>
<h2 id="java-nio">JAVA NIO</h2>
<p>对于NIO，如果TCP 的buffer中有数据，就把数据从网卡读到内存，并且返回给用户；反之则直接返回0，永远不会阻塞。下面是一段比较典型的 NIO的处理代码。</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349071/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536722387417-731a3788-c013-4476-914f-e826c152176f.png" alt="carbon (2).png | center | 747x1046" title=""></p>
<p>在我们可以将 JAVA NIO和多路复用结合起来。这里<!-- raw HTML omitted -->也是最简单的Reactor模式：注册所有感兴趣的事件处理器，单线程轮询选择就绪事件，执行事件处理器。<!-- raw HTML omitted --></p>
<p>这里简单比较了一下以前的 BIO和现在的 NIO，新的 NIO 给我们带来了如下的好处。</p>
<ul>
<li>事件驱动模型</li>
<li>单线程处理多任务</li>
<li>非阻塞I/O，I/O读写不再阻塞，而是返回0</li>
<li>基于快的传输，比基于流的传输更高效</li>
<li>更高级的IO函数，零拷贝</li>
<li>允许IO多路复用</li>
</ul>
<h1 id="reactor-线程模型">Reactor 线程模型</h1>
<p>前面说了，我们有了 JAVA NIO ，可以用多路复用。有些同学可能会问，不能直接使用吗？答案是可以直接使用，</p>
<p>但是技术层面上的问题虽然解决了，在工程层面，实现一个高效没有问题的架构依然很难，而且这种多路复用，对编程思维有比较大的挑战，所以，工程层面还不够。因此，有了 Reactor 编程模型</p>
<p><!-- raw HTML omitted -->一般情况下，I/O 复用机制需要事件分发器，<!-- raw HTML omitted -->以上这个分发事件的模型太简单了。实际使用起来会有一些性能问题。目前比较流行的是 Reactor 和 Proactor，<!-- raw HTML omitted -->本文不介绍 Proactor 模型，有兴趣的同学可以自己学习。<!-- raw HTML omitted --></p>
<p>标准/典型的 Reactor 中定义了三个角色：</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349113/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536534817410-18ae8cd1-ed35-4c9e-99c1-7ded1d7e0bc8.png" alt="角色.png | center | 747x277" title=""></p>
<p>而一个标准的操作流程则是</p>
<ul>
<li>步骤1：等待事件到来（Reactor 负责）。</li>
<li>步骤2：将读就绪事件分发给用户定义的处理器（Reactor 负责）。</li>
<li>步骤3：读数据（用户处理器负责）。</li>
<li>步骤4：处理数据（用户处理器负责）。</li>
</ul>
<p>在这个标准之下，Reactor有几种演进模式可以选择。注意 Reactor 重点描述的是 IO部分的操作，包括两部分，连接建立和 IO读写。</p>
<h3 id="单线程模型">单线程模型</h3>
<p>Reactor 单线程模型指的是所有的IO操作都在同一个NIO线程上面完成，NIO线程的职责如下：</p>
<ol>
<li>作为 NIO 服务端，接收客户端的 TCP 连接；</li>
<li>作为 NIO 客户端，向服务端发起 TCP 连接；</li>
<li>读取通信对端的请求或者应答消息；</li>
<li>向通信对端发送消息请求或者应答消息。</li>
</ol>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349152/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536532657207-fdd0cc07-da7c-4f70-a363-88fbab39247c.png" alt="Reactor 单线程.png | center | 747x188" title=""></p>
<p>这是最基本的单 Reactor 单线程模型。其中 Reactor 线程，负责多路分离套接字，有新连接到来触发 connect 事件之后，交由 Acceptor 进行处理，有 IO 读写事件之后交给 hanlder 处理。</p>
<p>Acceptor 主要任务就是构建 handler ，在获取到和 client 相关的 SocketChannel 之后 ，绑定到相应的 handler上，对应的 SocketChannel 有读写事件之后，基于 reactor 分发,hanlder 就可以处理了（所有的 IO 事件都绑定到selector 上，由 Reactor 分发）。</p>
<p>该模型 适用于处理器链中业务处理组件能快速完成的场景。不过，这种单线程模型不能充分利用多核资源，所以实际使用的不多。</p>
<h3 id="多线程模型">多线程模型</h3>
<p><!-- raw HTML omitted --><!-- raw HTML omitted -->Reactor 多线程模型与单线程模型最大的区别就是将 IO 操作和非 IO 操作做了分离。效率提高。<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<!-- raw HTML omitted -->
<p>Reactor多线程模型的特点：</p>
<ol>
<li>有专门一个NIO线程-Acceptor 线程用于监听服务端，主要接收客户端的 TCP 连接请求；</li>
<li>网络 IO 操作-读、写等由一个单独的 NIO 线程池负责，线程池可以采用标准的 JDK 线程池实现，它包含一个任务队列和 N 个可用的线程，由这些 NIO 线程负责消息的解码、处理和编码；</li>
</ol>
<h3 id="主从多线程模型">主从多线程模型</h3>
<p>这个也是目前大部分 RPC 框架，或者服务端处理的主要选择。</p>
<p><!-- raw HTML omitted --><!-- raw HTML omitted -->Reactor 主从多线程模型的特点：<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<p><!-- raw HTML omitted --><!-- raw HTML omitted -->服务端用于接收客户端连接的不再是个1个单独的 NIO 线程，而是一个独立的 NIO 线程池。<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349256/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536532679974-bccc45b0-60da-4213-b197-9b3fc9b6a362.png" alt="Reactor 主从.png | center | 747x172" title=""></p>
<p>主要的工作流程</p>
<ol>
<li>MainReactor 将连接事件分发给 Acceptor</li>
<li><!-- raw HTML omitted --><!-- raw HTML omitted -->Acceptor 接收到客户端 TCP 连接请求处理完成后(可能包含接入认证，黑名单等)，将新创建的 SocketChannel 注册到 IO 线程池(sub reactor线程池)的某个IO线程上，Acceptor 线程池仅仅只用于客户端的登陆、握手和安全认证。<!-- raw HTML omitted --><!-- raw HTML omitted --></li>
<li>SubReactor<!-- raw HTML omitted --><!-- raw HTML omitted --> 负责 SocketChannel 的读写和编解码工作。其 IO 线程负责后续的 IO 操作。<!-- raw HTML omitted --><!-- raw HTML omitted --></li>
</ol>
<h1 id="sofarpc-线程模型">SOFARPC 线程模型</h1>
<h2 id="整体线程模型">整体线程模型</h2>
<p>对于 SOFARPC 来说，和底层的 SOFABolt 一起，在使用 Netty 的 Reactor 主从模型的基础上，支持业务线程池的选择。</p>
<p><img src="https://res.cloudinary.com/lyp/image/upload/v1544349300/hugo/blog.github.io/sofa-rpc/%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E5%89%96%E6%9E%90/1536536933466-923efa36-4c96-4097-a911-d2d0b57810d7.png" alt="SOFARPC 线程.png | center | 747x181" title=""></p>
<h3 id="线程模型">线程模型</h3>
<p>目前 SOFARPC 服务端的线程模型在综合考虑，和一些历史压测的数据支撑的情况下，我们选了主从线程模型，并对序列化和业务代码执行使用一个 BizThreadPool（允许对线程池的核心线程数，队列等进行调整），或者自定义的线程池。将序列化，反序列化等。这些耗时的操作，全部放在了Biz线程池中，这样，可以有效地提高系统的整体吞吐量。</p>
<p>特别的，这里对于 header部分，我们将反序列化放在了 Worker线程中，这样，可以在对性能影响极低的情况下，可以提供一些额外的好处，比如允许业务配置接口对应的线程池。</p>
<h3 id="默认执行步骤">默认执行步骤</h3>
<p>一次比较完整的 RPC 调用的时候，以下为默认的执行线程。</p>
<ul>
<li>客户端
         长连接：Netty-Worker 线程
         序列化请求/反序列化响应：发起请求的线程，如果是 callback，是新的一个线程。
 心跳：Netty-Worker 线程</li>
<li>服务端
端口：Netty-Boss 线程
长连接：Netty-Worker 线程
            心跳：Netty-Worker 线程
反序列化请求Header：Netty-Worker 线程
反序列化请求Body/序列化响应：SOFARPC 业务线程池</li>
</ul>
<h2 id="自定义业务线程池">自定义业务线程池</h2>
<p>SOFARPC 支持自定义业务线程池，可以为指定服务设置一个独立的业务线程池，和 SOFARPC 自身的业务线程池是隔离的。多个服务可以共用一个独立的线程池。</p>
<h3 id="实现原理">实现原理</h3>
<p>自定义线程池管理器封装服务接口和自定义线程池映射关系，用户创建配置自定义线程池，提供指定服务注册自定义线程池。</p>
<p>BOLT 支持部分反序列化，所以框架会在 IO 线程池提前反序列化请求的 Header 头部数据，注意，这部分一个普通的 Map，操作很快，一般不会成为瓶颈，Body 数据还是在业务线程内反序列化。</p>
<p>核心代码在自定义线程池管理器里：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">com<span style="color:#f92672">.</span><span style="color:#a6e22e">alipay</span><span style="color:#f92672">.</span><span style="color:#a6e22e">remoting</span><span style="color:#f92672">.</span><span style="color:#a6e22e">rpc</span><span style="color:#f92672">.</span><span style="color:#a6e22e">protocol</span><span style="color:#f92672">.</span><span style="color:#a6e22e">RpcRequestProcessor</span><span style="color:#960050;background-color:#1e0010">#</span>process 选择线程池

UserThreadPoolManager 注册线程池<span style="color:#960050;background-color:#1e0010">。</span>
</code></pre></div><!-- raw HTML omitted -->
<p>感兴趣的同学可以去看下。</p>
<h3 id="使用方式">使用方式</h3>
<p>请求处理过程，默认是一个线程池，当这个线程池出现问题则会造成整体的吞吐量降低。而有些业务场景，希望对核心的请求处理过程单独分配一个线程池。SOFARPC 提供线程池选择器设置到用户请求处理器里面，调用过程即可根据选择器的逻辑来选择对应的线程池避免不同请求互相影响。</p>
<p>通过sofa:global-attrs元素的 thread-pool-ref 属性为该服务设置自定义线程池。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-xml" data-lang="xml"><span style="color:#f92672">&lt;bean</span> <span style="color:#a6e22e">id=</span><span style="color:#e6db74">&#34;customExcutor&#34;</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;com.alipay.sofa.rpc.server.UserThreadPool&#34;</span> <span style="color:#a6e22e">init-method=</span><span style="color:#e6db74">&#34;init&#34;</span><span style="color:#f92672">&gt;</span>
    <span style="color:#f92672">&lt;property</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;corePoolSize&#34;</span> <span style="color:#a6e22e">value=</span><span style="color:#e6db74">&#34;10&#34;</span> <span style="color:#f92672">/&gt;</span>
    <span style="color:#f92672">&lt;property</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;maximumPoolSize&#34;</span> <span style="color:#a6e22e">value=</span><span style="color:#e6db74">&#34;10&#34;</span> <span style="color:#f92672">/&gt;</span>
    <span style="color:#f92672">&lt;property</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;queueSize&#34;</span> <span style="color:#a6e22e">value=</span><span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">/&gt;</span>
<span style="color:#f92672">&lt;/bean&gt;</span>
<span style="color:#f92672">&lt;sofa:service</span> <span style="color:#a6e22e">ref=</span><span style="color:#e6db74">&#34;helloService&#34;</span> <span style="color:#a6e22e">interface=</span><span style="color:#e6db74">&#34; com.alipay.sofa.rpc.service.HelloService&#34;</span><span style="color:#f92672">&gt;</span>
    <span style="color:#f92672">&lt;sofa:binding.bolt&gt;</span>
        <span style="color:#f92672">&lt;sofa:global-attrs</span> <span style="color:#a6e22e">thread-pool-ref=</span><span style="color:#e6db74">&#34;customExcutor&#34;</span><span style="color:#f92672">/&gt;</span>
    <span style="color:#f92672">&lt;/sofa:binding.bolt&gt;</span>
<span style="color:#f92672">&lt;/sofa:service&gt;</span>
</code></pre></div><h1 id="总结">总结</h1>
<p><!-- raw HTML omitted --><!-- raw HTML omitted -->通过这篇文章，我们介绍了几种常见的 IO 模型，介绍了 JAVA 中的 IO和 NIO，同时也介绍了 IO 模型在工程上实践不错的 Reactor 模型。<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<p>最后，介绍了<!-- raw HTML omitted --><!-- raw HTML omitted --> SOFARPC 的线程模型，希望大家对整个线程模型有一定的理解，如果对 SOFARPC 线程模型和自定义线程池有疑问的，也欢迎留言与我们讨论。<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<!-- raw HTML omitted -->
<hr>
<p>文章转自<a href="http://www.sofastack.tech/post/cimv6r">剖析 | SOFARPC 框架】之SOFARPC 线程模型剖析</a></p>


        <h2>微信公众号</h2>
<p>扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github，看看我都在了解什么技术，在页面底部可以找到我的Github。</p>
<img src="https://res.cloudinary.com/lyp/image/upload/v1581729955/hugo/blog.github.io/qrcode_for_sikekafeidou.jpg" alt="wechat-account-qrcode">


                <hr>

                <ul class="pager">
                    
                    <li class="previous">
                        <a href="/post/awesome-messagequeue/" data-toggle="tooltip" data-placement="top" title="AWESOME消息队列">&larr; AWESOME消息队列</a>
                    </li>
                    
                    
                    <li class="next">
                        <a href="/post/sofarpc-sync-async/" data-toggle="tooltip" data-placement="top" title="转|SOFARPC同步异步实现剖析">转|SOFARPC同步异步实现剖析 &rarr;</a>
                    </li>
                    
                </ul>

            
<script src="https://utteranc.es/client.js"
repo="liangyuanpeng/liangyuanpeng.github.io"
issue-term="title"
theme="github-light"
crossorigin="anonymous"
async>
</script>



            </div>

            


            
            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                sidebar-container">

                
                <section>
                    <hr class="hidden-sm hidden-xs">
                    <h5><a href="/tags/">FEATURED TAGS</a></h5>
                    <div class="tags">
                     
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/blog" title="blog">
                                blog
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/chirpstack" title="chirpstack">
                                chirpstack
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/ci/cd" title="ci/cd">
                                ci/cd
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/cloudnative" title="cloudnative">
                                cloudnative
                            </a>
                        
                    
                        
                            <a href="/tags/cncf" title="cncf">
                                cncf
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/docker" title="docker">
                                docker
                            </a>
                        
                    
                        
                            <a href="/tags/docker-compose" title="docker-compose">
                                docker-compose
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/fluentd" title="fluentd">
                                fluentd
                            </a>
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/halo" title="halo">
                                halo
                            </a>
                        
                    
                        
                            <a href="/tags/hugo" title="hugo">
                                hugo
                            </a>
                        
                    
                        
                            <a href="/tags/image" title="image">
                                image
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/iot" title="iot">
                                iot
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/kubernetes" title="kubernetes">
                                kubernetes
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/lorawan" title="lorawan">
                                lorawan
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/middleware" title="middleware">
                                middleware
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/mq" title="mq">
                                mq
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/ops" title="ops">
                                ops
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/prometheus" title="prometheus">
                                prometheus
                            </a>
                        
                    
                        
                    
                        
                    
                        
                            <a href="/tags/rpc" title="rpc">
                                rpc
                            </a>
                        
                    
                        
                    
                        
                            <a href="/tags/sofa" title="sofa">
                                sofa
                            </a>
                        
                    
                        
                            <a href="/tags/sofastack" title="sofastack">
                                sofastack
                            </a>
                        
                    
                        
                            <a href="/tags/springboot" title="springboot">
                                springboot
                            </a>
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                        
                    
                    </div>
                </section>



               

                
                
            </div>

            
            
            <div class="
            col-lg- col-lg-offset-2
            col-md-10 col-md-offset-1
            ">
            <section>
                <hr class="hidden-sm hidden-xs">
                

<h2>相关文章</h2>
<ul style="margin-bottom: 25px;">
    
    <li><a href="/post/sofarpc-sync-async/">转|SOFARPC同步异步实现剖析</a></li>
    
    <li><a href="/post/sofarpc-trace/">转|SOFARPC链路追踪剖析</a></li>
    
    <li><a href="/post/sofarpc-design/">转|SOFARPC框架之总体设计与扩展机制</a></li>
    
    <li><a href="/post/%E5%8E%BB%E5%93%AA%E5%84%BF%E7%BD%91%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0/">去哪儿网消息队列设计与实现</a></li>
    
    <li><a href="/post/awesome-messagequeue/">AWESOME消息队列</a></li>
    
    <li><a href="/post/deploy-apache-rocketmq/">Apache RocketMQ单机部署</a></li>
    
</ul>

            </section>
            </div>
            


        </div>
    </div>
</article>






<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <ul class="list-inline text-center">
                   
                    
                    <li>
                        <a target="_blank" href="https://github.com/liangyuanpeng">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                   
                    
                    <li>
                        <a href="mailto:liangyuanpengem@163.com">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-envelope fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
		    

                    
                    <li>
                        <a href="https://twitter.com/lan31793328">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                    
                    
                    <li>
                        <a target="_blank" href="https://www.zhihu.com/people/liangyuanpeng">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa  fa-stack-1x fa-inverse">知</i>
                            </span>
                        </a>
                    </li>
		    
                    
                    <li>
                        <a target="_blank" href="https://weibo.com/u/1908782280">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-weibo fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
		    

                    

		    
                    
                    
                </ul>
		<p class="copyright text-muted">
                    Copyright &copy; Hi,I`m lan , 2018
                    <br>
                    <a href="https://themes.gohugo.io/hugo-theme-cleanwhite">CleanWhite Hugo Theme</a> by <a href="https://zhaohuabing.com">Huabing</a> |
                    <iframe
                        style="margin-left: 2px; margin-bottom:-5px;"
                        frameborder="0" scrolling="0" width="100px" height="20px"
                        src="https://ghbtns.com/github-btn.html?user=zhaohuabing&repo=hugo-theme-cleanwhite&type=star&count=true" >
                    </iframe>
                </p>
            </div>
        </div>
    </div>
</footer>




<script>
    function async(u, c) {
      var d = document, t = 'script',
          o = d.createElement(t),
          s = d.getElementsByTagName(t)[0];
      o.src = u;
      if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
      s.parentNode.insertBefore(o, s);
    }
</script>






<script>
    
    if($('#tag_cloud').length !== 0){
        async("/js/jquery.tagcloud.js",function(){
            $.fn.tagcloud.defaults = {
                
                color: {start: '#bbbbee', end: '#0085a1'},
            };
            $('#tag_cloud a').tagcloud();
        })
    }
</script>


<script>
    async("https://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.js", function(){
        var $nav = document.querySelector("nav");
        if($nav) FastClick.attach($nav);
    })
</script>







<script>
    
    var _baId = 'fad9c137f8ce239f9b323d36c871f8e6';

    
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?" + _baId;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
</script>







</body>
</html>
